﻿#define _CRT_SECURE_NO_WARNINGS 1
#include <stdio.h>

//实现strlen
//int my_strlen(char* s)
//{
//	int count = 0;
//	char* p = s;
//	while (*p != '\0')
//	{
//		count++;
//		p++;
//	}
//	return count;
//}
//#include <string.h>
//int main()
//{
//	char ch[] = "abcdef";
//	int len1 = strlen(ch);
//	int len2 = my_strlen(&ch);
//	printf("%d\n", len1);
//	printf("%d", len2);
//
//	return 0;
//}

//字符分类函数
//头文件是ctype.h


//头文件ctype.h下的函数isalnum

//作用：判断是否为字母和数字，如a~z，A~Z，0~9.

//返回类型为 int ,是字母和数字返回非0，不是返回0

//函数展现：
//#include <ctype.h>
//int main()
//{
//	printf("%d\n", isalnum('-'));//0
//	printf("%d\n", isalnum('0'));//非0
//	printf("%d\n", isalnum('a'));//非0
//	printf("%d\n", isalnum('A'));//非0
//	printf("%d\n", isalnum('%'));//0
//	return 0;
//}

//函数的实现 - my_isalnum
//#include <ctype.h>
//int my_isalnum(int s)
//{
//	if ((s >= 'a' && s <= 'z') || (s >= 'A' && s <= 'Z') || (s >= '0' && s <= '9'))
//	{
//		return 8;
//	}
//	else
//		return 0;
//}
//int main()
//{
//	int len = my_isalnum('5');
//	printf("%d\n", len);
//	return 0;
//}
//



//头文件ctype.h下的函数islower

//作用判断是否为小写字母，如果是返回非0，如果不是返回0

//代码展现
//#include <ctype.h>
//int main()
//{
//	printf("%d\n", islower('a'));//非0
//	printf("%d\n", islower('A'));//0
//	printf("%d\n", islower('*'));//0
//	printf("%d\n", islower('5'));//0
//	printf("%d\n", islower('b'));//非0
//	printf("%d\n", islower('c'));//非0
//	return 0;
//}

//代码的实现 - my_islower
//#include <ctype.h>
//int my_islower(int s)
//{
//	if (s >= 'a' && s <= 'z')
//	{
//		return 1;
//	}
//	else
//	{
//		return 0;
//	}
//}
//int main()
//{
//	int ret = my_islower('c');
//	printf("%d\n", ret);
//	return 0;
//}


//写⼀个代码，将字符串中的⼩写字⺟转⼤写，其他字符不变。
//#include<stdio.h>
//#include<ctype.h>
//
//int main()
//{
//	int i = 0;
//	char str[] = "ou qu yang.\n";
//	while (str[i])
//	{
//		if (islower(str[i]))
//			str[i] -= 32;
//		putchar(str[i]);//打印
//		i++;
//	}
//	return 0;
//}


//字符转换函数
//#include <ctype.h>
//int tolower(int c);//将传进去的参数大写字母转换为小写
//int toupper(int c);//将传进去的参数小写字母转换为大写

//#include<ctype.h>
//int main()
//{
//	int i = 0;
//	char str[] = "Ou qu yaNg.\n";
//	while (str[i])
//	{
//		if (islower(str[i]))
//			str[i] = toupper(str[i]);
//		putchar(str[i]);//打印
//		i++;
//	}
//	return 0;
//}


//转化为小写字母
//#include<ctype.h>
//int main()
//{
//	int i = 0;
//	char str[] = "Ou qu yaNg.\n";
//	while (str[i])
//	{
//		if (isupper(str[i]))
//			str[i] = tolower(str[i]);
//		putchar(str[i]);//打印
//		i++;
//	}
//	return 0;
//}



//strlen函数的使用和模拟实现

//strlen函数计算字符串在'\0'前字符的个数
//遇到'\0'就结束
//返回类型为无符号的 - size_t
//使用需要包含头文件<string.h>

//#include <stdio.h>
//#include<string.h>
//int main()
//{
//	const char* str1 = "abcdefg";
//	const char* str2 = "bbb";
//	if (strlen(str2) - strlen(str1) > 0)
//	{
//		printf("str2>str1\n");
//	}
//	else
//	{
//		printf("str2<str1\n");
//	}
//	return 0;
//}

//因为返回的是无符号类型，所以即使算出负数也会去掉符号



//strlen函数的实现
//int my_strlen(char* s)
//{
//	char* p = s;
//	int count = 0;
//	while (*p != '\0')
//	{
//		count++;
//		p++;
//	}
//	return count;
//}
//
//int main()
//{
//	char arr[] = "abcdefg";
//	int ret = my_strlen(arr);
//	printf("%d\n",ret);
//	return 0;
//}



//17.字符指针变量
//在指针类型中我们通常使用char*

//代码展示
//int main()
//{
//	char ch = 'w';
//	char* p = &ch;
//	*p = 's';
//	printf("%c", ch);
//	return 0;
//}

//int main()
//{
//	char ch[] = "hello ouquyang!";
//	char* pch = &ch;
//	printf("%s", pch);
//	return 0;
//}

//上述代码中，并不是将字符串放入指针中，而是将字符或字符串首字符的
//地址存放在指针中，在使用时顺藤摸瓜就可以打印出后面内容了

//如剑指offer上的一题
//int main()
//{
//	char str1[] = "hello bit.";
//	char str2[] = "hello bit.";
//	const char* str3 = "hello bit.";
//	const char* str4 = "hello bit.";
//	if (str1 == str2)
//		printf("str1 and str2 are same\n");
//	else
//		printf("str1 and str2 are not same\n");
//	if (str3 == str4)
//		printf("str3 and str4 are same\n");
//	else
//		printf("str3 and str4 are not same\n");
//	return 0;
//}

//字符数组str1和str2都是独立开创的两个空间，所以指向的对象是不一样的
//而字符指针str3和str4指向的是同一块空间，同一个地址，所以是相同的。


//18.数组指针变量

//之前我们知道指针数组是用来存放指针的数组，数组中存放的是地址（指针）
//那么数组指针变量是指针变量


//整型指针变量：int* pint ;存放的是整形变量的地址，
// 能够指向整形数据的指针


//浮点型指针变量：float* pf;存放浮点型变量的地址，
// 能够指向浮点型数据的指针

//判断一下
//int* p1[5];//指针数组 - 用来存放指针的数组
//int(*p2)[5];//数组指针 - 用来指向数组地址的指针


//int (*p)[10];
//解析：p先与*结合，说明p是一个指针变量，然后指向的是一个大小为10
//整型的数组，所以p是指针，指向一个数组，称作数组指针



//19.数组指针如何初始化

//int arr[10] = { 0 };
//&arr;//得到整个数组的地址

//int main()
//{
//	int arr[10] = { 0 };
//	int(*p)[10] = &arr;
//	return 0;
//}

//数组指针类型解析：
//int - p指向的数组元素类型
//*p - 说明p是数组指针的变量名
//[10] - p指向数组的元素个数


//20.二维数组传参的本质

//void text(int arr[3][3], int r, int c)
//{
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < r; i++)
//	{
//		
//		for (j = 0; j < c; j++)
//		{
//			printf("%d ", arr[i][j]);
//		}
//		printf("\n");
//	}
//}
//
//void text2(int(*p)[3], int r, int c)
//{
//	int i = 0;
//	int j = 0;
//	for (i = 0; i < r; i++)
//	{
//		for (j = 0; j < c; j++)
//		{
//			printf("%d ", *(*(p + i) + j));
//		}
//		printf("\n");
//	}
//}
//int main()
//{
//	int arr[3][3] = { {1,2,3},{4,5,6},{7,8,9} };
//	text(arr, 3, 3);
//	printf("\n");
//	text2(arr, 3, 3);
//	return 0;
//}

//21.函数指针变量

//函数存在地址
//void text()
//{
//	printf("hehe\n");
//}
//int main()
//{
//	printf("text  = %p\n", text);
//	printf("&text = %p\n", &text);
//
//	return 0;
//}


//void test()
//{
//	printf("hehe\n");
//}
//void (*pf1)() = &test;
//void (*pf2)() = test;
//int Add(int x, int y)
//{
//	return x + y;
//}
//int(*pf3)(int, int) = Add;
//int(*pf3)(int x, int y) = &Add;//x和y写上或者省略都是可以的


//void (*p)(int, int)
//void - p指向函数的返回类型
//*p - 函数指针变量名
//(int, int)p指向函数参数类型和个数


//函数指针变量的使用
//通过函数指针调用指针指向的函数

//int add(int x, int y)
//{
//	return x + y;
//}
//
//int main()
//{
//	int(*p)(int, int) = add;
//
//	printf("%d\n", (*p)(2, 3));
//
//	printf("%d\n", p(2, 5));
//
//	return;
//}


